package com.myzl.coal.service.impl;

import cn.hutool.core.util.ObjUtil;
import com.myzl.coal.mongo.component.MongoComponent;
import com.myzl.coal.mongo.domain.HistoryData;
import com.myzl.coal.service.ICacheBasicService;
import com.myzl.common.enums.DeviceCommandEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author cew
 * @date
 */
@Slf4j
@Data
@Service
public class CacheBasicServiceImpl implements ICacheBasicService {

    private final MongoComponent mongoComponent;

    @Override
    @Cacheable(value = "doubleOrderBasicFlow",key = "#deviceId")
    public Map<String, Object> cacheBasicData(Integer deviceId, List<HistoryData> densityList){
        Map<String, Object> result;
        result = getCacheMap(deviceId, densityList);
        return result;
    }
    @Override
    @CachePut(value = "doubleOrderBasicFlow",key = "#deviceId")
    public Map<String, Object> updateCacheBasicData(Integer deviceId,List<HistoryData> densityList){
        Map<String, Object> result;
        result = getCacheMap(deviceId, densityList);
        return result;
    }

    @Override
    @CacheEvict(value = "doubleOrderBasicFlow",key = "#deviceId")
    public void clearCache(Integer deviceId) {
        log.info("已清除设备{}的基线数据",deviceId);
    }

    private Map<String, Object> getCacheMap(Integer id, List<HistoryData> densityList) {
        Map<String, Object> result = new HashMap<>();
        BigDecimal volume = new BigDecimal("0.00");
        BigDecimal flow = new BigDecimal("0.00");
        int i = 1;
        HistoryData historyData = null;
        Sort descSort = Sort.by(Sort.Order.desc("createTime"));
        HistoryData volumeHistoryData = null;
        while (volume.compareTo(new BigDecimal("0.00")) == 0 && ObjUtil.isNull(volumeHistoryData)){
            if (densityList.size() > i){
                historyData = densityList.get(i);
                Criteria volumeCriteria = new Criteria();
                volumeCriteria.andOperator(
                        Criteria.where("deviceId").is(id),
                        Criteria.where("dictValue").is(DeviceCommandEnum.CUMULATIVE_VOLUME.getCode()),
                        Criteria.where("createTime").gte(historyData.getStartTime()),
                        Criteria.where("createTime").lt(historyData.getEndTime())
                );
                List<HistoryData> volumeList = mongoComponent.selectList(volumeCriteria, 1, descSort, HistoryData.class);
                if (volumeList.size() > 0) {
                    volumeHistoryData =  volumeList.get(0);
                }
                i++;
            } else {
                break;
            }
        }

        Criteria flowCriteria = new Criteria();
        flowCriteria.andOperator(
                Criteria.where("deviceId").is(id),
                Criteria.where("dictValue").is(DeviceCommandEnum.CUMULATIVE_FLOW.getCode()),
                Criteria.where("createTime").gte(historyData.getStartTime()),
                Criteria.where("createTime").lt(historyData.getEndTime())
        );
        List<HistoryData> flowList = mongoComponent.selectList(flowCriteria, 1, descSort, HistoryData.class);
        HistoryData flowHistoryData = null;
        if (flowList.size() > 0){
            flowHistoryData= flowList.get(0);
        }
        if (ObjUtil.isNotNull(volumeHistoryData) && ObjUtil.isNotNull(flowHistoryData)){
            volume = new BigDecimal(volumeHistoryData.getDataValue());
            flow = new BigDecimal(flowHistoryData.getDataValue());
        }

        BigDecimal density = new BigDecimal(historyData.getDataValue());
        String densityId = historyData.getId();
        result.put("densityId", densityId);
        result.put("volume", volume);
        result.put("flow", flow);
        result.put("density", density);
        return result;
    }


}
